#pragma once
#include <string>
#include <map>
#include "libutilsbase.h"
using namespace System;
using namespace System::Collections::ObjectModel;
using namespace System::Runtime::InteropServices;
using namespace System::Collections::Generic;

public 	ref struct
CastHelper
{
public:
	generic <typename Target>
	Target CastToNet(IntPtr source) 
	{
		Target ret = (Target)Marshal::PtrToStructure(source,Target::typeid);
		return ret;
	}

	IntPtr GetGlobMemory()
	{
		static IntPtr ptr = Marshal::AllocHGlobal(1024*1024);
		return ptr;
	}


	template<typename TargetNative,typename SourceNet> 
	TargetNative CastToNative(SourceNet source)
	{
		IntPtr ptr = GetGlobMemory();//Marshal::AllocHGlobal(sizeof(TargetNative));
		Marshal::StructureToPtr(source,ptr,false);

		TargetNative ret = *((TargetNative*)(void*)ptr);
		return ret;
	}

public:
	static std::string Cast_std_string (System::String^ s);
	static std::wstring Cast_std_wstring (System::String ^ s);

	static System::String^ Cast_String(const char* s);
	static System::String^ Cast_String(const wchar_t* s);

	static System::String^ Cast_String(const std::string& s);
	static System::String^ Cast_String(const std::wstring& s);

public:
	Dictionary<System::String^,System::String^>^ ToNetMap( const std::map<tstring,tstring>& _map );


	std::map<tstring,tstring> ToMap( Dictionary<System::String^,System::String^>^ input );

};




public ref class WindowWrapper : System::Windows::Forms::IWin32Window
{
public:	
	WindowWrapper(IntPtr handle)
	{
		_hwnd = handle;
	}
public:
	property IntPtr Handle
	{
		virtual IntPtr get(void){return _hwnd;};
	};
private: IntPtr _hwnd;
}; 



class NetHelper
{
public:
	static System::Reflection::PropertyInfo^ GetNamedProperty(System::Type^ type, System::String^ name, System::Reflection::BindingFlags bindingFlags)
	{
		return type->GetProperty(name, bindingFlags);
	}
	static System::Object^ GetPropertyValue(System::Object^ obj, System::String^ name)
	{
		if(obj == nullptr)
			return nullptr;
		System::Reflection::PropertyInfo^ info = GetNamedProperty(obj->GetType(), name, System::Reflection::BindingFlags::Public | System::Reflection::BindingFlags::Instance);
		if (info != nullptr)
		{
			return info->GetValue(obj, nullptr);
		}
		return nullptr;
	}
};
